from fastapi import Depends, HTTPException
from typing import List, Dict, Any
from sqlalchemy.exc import NoResultFound

from basic.s3 import S3
from basic.database import AsyncSession, get_db
from .interfaces import IRepoService
from .repository.repoRepository import (
    create_repo,
    delete_repo,
    update_repo_name,
    get_repo,
    get_repos
)

class RepoService(IRepoService):
    def __init__(
        self, 
        db: AsyncSession = Depends(get_db), 
        s3: S3 = Depends(S3)
    ):
        super().__init__()
        self.db = db
        self.s3 = s3

    async def mount_repo(self, name: str) -> Dict[str, Any]:
        try:
            # 创建S3存储桶
            self.s3.create_bucket(name)
            
            async with self.db.begin():
                # 使用仓库存储库创建仓库
                repo, entry_key = await create_repo(self.db, name)
                
                # 提交事务
                await self.db.commit()
                
            # 返回字典
            return {
                "repo_key": repo.key, 
                "entry_key": entry_key,
                "name": repo.name,
                "created_at": repo.created_at.isoformat() if repo.created_at else None,
                "updated_at": repo.updated_at.isoformat() if repo.updated_at else None
            }
            
        except Exception as e:
            await self.db.rollback()
            print(f"Error creating repository: {e}")
            raise e

    async def unmount_repo(self, repo_key: str) -> Dict[str, str]:
        """
        删除一个仓库
        
        Args:
            repo_key: 仓库键
            
        Returns:
            删除的仓库名称
        """
        try:
            async with self.db.begin():
                # 获取仓库
                repo = await get_repo(self.db, repo_key)
                if not repo:
                    raise HTTPException(status_code=404, detail="Repository not found")
                
                repo_name = repo.name
                
                # 删除仓库
                await delete_repo(self.db, repo_key)
                
                # 提交事务
                await self.db.commit()
            
            # 删除存储桶（确保在数据库操作成功后执行）
            self.s3.delete_bucket(repo_name)
                
            return {"name": repo_name}
            
        except HTTPException as he:
            raise he
        except Exception as e:
            await self.db.rollback()
            print(f"Error deleting repository: {e}")
            raise HTTPException(status_code=500, detail=str(e))

    async def update_repo(self, repo_key: str, update_key: str, update_value: str) -> Dict[str, str]:
        """
        更新仓库的键值对
        
        Args:
            repo_key: 仓库键
            update_key: 要更新的键
            update_value: 要更新的值
            
        Returns:
            更新后的仓库键
        """
        try:
            async with self.db.begin():
                match update_key:
                    case "name":
                        updated_repo = await update_repo_name(self.db, repo_key, update_value)
                    case _:
                        raise HTTPException(status_code=400, detail="Invalid update key")
                
                # 提交事务
                await self.db.commit()
                
            return {"repo_key": updated_repo.key}
            
        except HTTPException as he:
            raise he
        except Exception as e:
            await self.db.rollback()
            print(f"Error updating repository: {e}")
            raise HTTPException(status_code=500, detail=str(e))

    async def list_repos(self):
        """
        获取仓库列表
        
        Args:
            
        Returns:
            仓库列表
        """
        try:
            # 获取所有仓库及其根目录
            repos_with_entries = await get_repos(self.db)
               
            # 转换为字典列表
            items = [
                {
                    "name": repo.name,
                    "repo_key": repo.key,
                    "entry_key": entry.key
                }
                for repo, entry in repos_with_entries
            ]
            
            return items
            
        except Exception as e:
            print(f"Error getting repositories: {e}")
            raise HTTPException(status_code=500, detail=str(e))
        